import React from "react"
import Arrangement from "./Arrangement"
import Board from "./Board"
import { calculateWinner } from "../helps"

export default class Game extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      history: [
        // 这里如果只有唯一数据 squares，那么使用数组而非对象也可以，但使用对象一是可以有一个属性名称，另一个原因是可以记录更多的数据。
        {
          squares: Array(9).fill(null),
          stepCoord: null
        }
      ],
      stepNumber: 0,
      xIsNext: true,
      isAscending: true,
    }
  }

  componentDidUpdate() {
    const { stepNumber } = this.state
    const nodeBtns = document.querySelectorAll("ol li button")
    nodeBtns.forEach(ele => {
      ele.className = ""
    })
    nodeBtns[stepNumber].className = "moveBtn-current"
  }

  handleClick(i) {
    const { history, stepNumber, isAscending } = this.state
    const nodeBtns = document.querySelectorAll("ol li button")
    let newHistory, current
    // 升序与降序排列计算当前 history 的方式是不一样的
    if (isAscending) {
      // 获取当前 step 的 history
      newHistory = history.slice(0, stepNumber + 1)
      // 获取当前 history 中的状态
      current = newHistory[newHistory.length - 1]
    } else {
      newHistory = history.slice(stepNumber - history.length)
      current = newHistory[0]
    }

    // 获取当前 history 中的 squares 值
    const squares = current.squares.slice()
    if (calculateWinner(squares) || squares[i]) {
      return
    }

    let coordinate = []

    for (let i = 1; i < 4; i++) {
      for (let j = 1; j < 4; j++) {
        coordinate.push(`(${j}, ${i})`)
      }
    }

    // const coordinate = [
    //   "(1,1)",
    //   "b-1",
    //   "c-1",
    //   "a-2",
    //   "b-2",
    //   "c-2",
    //   "a-3",
    //   "b-3",
    //   "c-3"
    // ]

    // 判断是升序还是降序，从而决定新的 history 添加到 history 数组中的头部还是尾部，并且决定 stepNumber 的值
    const currentHistory = [
      {
        squares: squares,
        stepCoord: coordinate[i]
      }
    ]
    let newStepNumber
    if (isAscending) {
      newHistory = newHistory.concat(currentHistory)
      newStepNumber = newHistory.length - 1
      nodeBtns.forEach(ele => {
        ele.className = "moveBtn-a"
      })
    } else {
      newHistory = currentHistory.concat(newHistory)
      newStepNumber = 0
      nodeBtns.forEach(ele => {
        ele.className = "moveBtn-d"
      })
    }

    // if (this.state.squares[i] === null) {  //我的逻辑是当没有内容时做处理，而他的逻辑是当有内容时不做处理
    squares[i] = this.state.xIsNext ? "X" : "O"
    this.setState({
      history: newHistory,
      // history.length 正好比当前 stepNumber 多 1
      stepNumber: newStepNumber,
      xIsNext: !this.state.xIsNext
    })
    // }

    // 当棋盘中没有棋子并且没有人获胜时，显示平局
    if (isAscending) {
      if (newHistory.length === 10 && !calculateWinner(newHistory[9].squares)) {
        setTimeout(() => {
          alert("平局")
        }, 100)
      }
    } else {
      if (newHistory.length === 10 && !calculateWinner(newHistory[0].squares)) {
        setTimeout(() => {
          alert("平局")
        }, 100)
      }
    }
  }

  jumpTo(step, e) {
    // 改变样式，使当前被点击的按钮高亮
    const nodeBtns = document.querySelectorAll("ol li button")
    nodeBtns.forEach(ele => {
      ele.className = ""
    })
    e.target.className = "moveBtn-current"

    this.setState({
      stepNumber: step,
      xIsNext: step % 2 === 0
    })
  }

  switchArrangement = () => {
    const history = this.state.history.slice()
    const ol = document.querySelector("ol")

    history.reverse()

    // 让 ol 的序列号倒叙
    ol.reversed = ol.reversed ? false : true

    this.setState({
      history,
      isAscending: !this.state.isAscending,
      stepNumber: history.length - this.state.stepNumber - 1,
    })
  }

  render() {
    const { history, isAscending } = this.state
    const current = history[this.state.stepNumber]
    const winnerObject = calculateWinner(current.squares)
    const winner = winnerObject && winnerObject.winner
    const moves = history.map((step, move) => {
      const desc = step.stepCoord
        ? "Go to move #" + move + " & coordinate: " + history[move].stepCoord
        : "Go to game start"
      return (
        <li key={move}>
          <button
            className={isAscending ? "moveBtn-a" : "moveBtn-d"}
            onClick={e => this.jumpTo(move, e)}
          >
            {desc}
          </button>
        </li>
      )
    })

    let status
    if (winner) {
      status = "Winner: " + winner
    } else {
      status = "Next player: " + (this.state.xIsNext ? "X" : "O")
    }

    return (
      <div className="game">
        <div className="game-board">
          <Board
            squares={current.squares}
            onClick={i => this.handleClick(i)}
            winLines={winnerObject && winnerObject.winLines}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{moves}</ol>
        </div>
        <Arrangement
          isAscending={this.state.isAscending}
          switchArrangement={this.switchArrangement}
        />
      </div>
    )
  }
}
